package com.runjian.rundo.iot.agent.common.thread;

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import lombok.extern.slf4j.Slf4j;

/**
 * 线程池监控
 *
 * @author CaoQingHua
 */
@Slf4j
public class ThreadPoolMonitor {
    static ScheduledExecutorService monitor;

    static {
        monitor = Executors.newScheduledThreadPool(1);
    }

    /**
     * 添加线程监控
     *
     * @param threadPoolName 线程池名称
     * @param frequency 日志输出频率
     * @param threadPoolTaskExecutor 线程池
     */
    public static void addThreadPoolMonitor(String threadPoolName, Long frequency, ThreadPoolExecutor threadPoolTaskExecutor) {
        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();

        monitor.scheduleAtFixedRate(() -> {

            int activeCount = threadPoolTaskExecutor.getActiveCount();
            long corePoolSize = threadPoolTaskExecutor.getCorePoolSize();
            long completedTaskCount = threadPoolTaskExecutor.getCompletedTaskCount();
            long queueSize = threadPoolTaskExecutor.getQueue().size();
            int poolSize = threadPoolTaskExecutor.getPoolSize();
            int maximumPoolSize = threadPoolTaskExecutor.getMaximumPoolSize();

            log.info("--------------------------{}线程池状态--------------------------", threadPoolName);
            log.info("{}线程池活跃线程数： {}", threadPoolName, activeCount);
            log.info("{}线程池核心线程数: {}", threadPoolName, corePoolSize);
            log.info("{}线程池待执行任务数: {}", threadPoolName, queueSize);
            log.info("{}线程池已执行任务数: {}", threadPoolName, completedTaskCount);
            log.info("{}线程池大小: {}", threadPoolName, poolSize);
            log.info("{}线程池最大数量: {}", threadPoolName, maximumPoolSize);
            log.info("--------------------------{}线程池状态打印结束--------------------------", threadPoolName);
        }, 60, frequency, TimeUnit.SECONDS);
    }

}
